package com.bookhouse.dao.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.bookhouse.dao.BaseDao;
import org.hibernate.bytecode.buildtime.spi.ClassDescriptor;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

public class BaseDaoImpl<T> implements BaseDao<T> {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    protected final Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    protected final Session getCurrentSession1() {
        return sessionFactory.openSession();
    }

    @SuppressWarnings("unchecked")
    public T get(Class<T> entityClazz, Serializable id) {
        return (T) getCurrentSession().get(entityClazz, id);
    }

    public Serializable save(T entity) {
        return getCurrentSession().save(entity);
    }

    public void update(T entity) {
        getCurrentSession().saveOrUpdate(entity);
    }

    public void delete(T entity) {
        getCurrentSession().delete(entity);
    }

    public void delete(Class<T> entityClazz, Serializable id) {
        getCurrentSession()
                .createQuery("delete " + entityClazz.getSimpleName() + " en where en.id = ?0").setParameter("0", id)
                .executeUpdate();
    }

    public List<T> findAllList(Class<T> entityClazz) {
        return find("select en from " + entityClazz.getSimpleName() + " en");
    }

    public Set<T> findAllSet(Class<T> entityClazz) {
        return (Set<T>) find("select en from" + entityClazz.getSimpleName() + "en");
    }

    public long findCount(Class<T> entityClazz) {
        List<?> l = find("select count(*) from " + entityClazz.getSimpleName());
        if (l != null && l.size() == 1) {
            return (Long) l.get(0);
        }
        return 0;
    }


    @Override
    public List<T> find(String hql) {
        return (List<T>) getCurrentSession1().createQuery(hql).list();
    }

    @SuppressWarnings("unchecked")
    protected List<T> find(String hql, Object... params) {
        Query query = getCurrentSession().createQuery(hql);
        for (int i = 0, len = params.length; i < len; i++) {
            query.setParameter(i + "", params[i]);
        }
        return (List<T>) query.list();
    }

    @SuppressWarnings("unchecked")
    protected List<T> findByPage(String hql, int pageNo, int pageSize) {
        return getCurrentSession().createQuery(hql).setFirstResult((pageNo - 1) * pageSize)
                .setMaxResults(pageSize).list();
    }

    @SuppressWarnings("unchecked")
    protected List<T> findByPage(String hql, int pageNo, int pageSize, Object... params) {
        Query query = getCurrentSession().createQuery(hql);
        for (int i = 0, len = params.length; i < len; i++) {
            query.setParameter(i + "", params[i]);
        }
        return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
    }

}
